package com.baidu.camera.ui;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.SurfaceTexture;
import android.hardware.usb.UsbDevice;
import android.media.AudioManager;
import android.media.SoundPool;
import android.media.ThumbnailUtils;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v4.app.NavUtils;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;

import com.baidu.camera.R;
import com.baidu.camera.usbcamera.CameraViewInterface;
import com.baidu.camera.usbcamera.ControlItem;
import com.baidu.camera.usbcamera.MediaAudioEncoder;
import com.baidu.camera.usbcamera.MediaEncoder;
import com.baidu.camera.usbcamera.MediaMuxerWrapper;
import com.baidu.camera.usbcamera.MediaVideoEncoder;
import com.baidu.camera.utils.ToastUtils;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;
import com.serenegiant.usb.CameraDialog;
import com.serenegiant.usb.DeviceFilter;
import com.serenegiant.usb.IFrameCallback;
import com.serenegiant.usb.USBMonitor;
import com.serenegiant.usb.UVCCamera;

import org.androidannotations.annotations.EActivity;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.UUID;

@EActivity()
public class USBCameraActivity extends AppCompatActivity implements SurfaceHolder.Callback {
    private String TAG = "USBCameraActivity";
    //devices related
    private USBMonitor usbMonitor;
    private android.widget.TextView note;
    private List<DeviceFilter> mFilter;

    private GoogleApiClient mGoogleApiClient;

    private Surface mSurface;
    private SurfaceView uvcView;

    private UVCCamera mCamera;


    private int mWidth = 200;
    private int mHeight = 200;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_usb_camera);
        initView();
    }

    private void initView() {
        buildGoogleApiClient();
        //init controls

        //init usb monitor for finding usb devices
        usbMonitor = new USBMonitor(this, mOnDeviceConnectListener);//init usb monitor
        usbMonitor.register();
        mFilter = DeviceFilter.getDeviceFilters(this, R.xml.device_filter);
        this.uvcView = (SurfaceView) findViewById(R.id.uvcView);
        this.uvcView.getHolder().addCallback(this);
    }

    @Override
    protected void onPause() {
        usbMonitor.unregister();//unregister
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        usbMonitor.destroy();
        super.onDestroy();
    }

    //devices conn listener
    private final USBMonitor.OnDeviceConnectListener mOnDeviceConnectListener = new USBMonitor.OnDeviceConnectListener() {
        @Override
        public void onAttach(final UsbDevice device) {
            Toast.makeText(USBCameraActivity.this, R.string.usbattached, Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onConnect(final UsbDevice device, final USBMonitor.UsbControlBlock ctrlBlock, final boolean createNew) {
            initCamera(ctrlBlock);
            startPreview();
        }

        @Override
        public void onDisconnect(final UsbDevice device, final USBMonitor.UsbControlBlock ctrlBlock) {
            closeCamera();
        }

        @Override
        public void onDettach(final UsbDevice device) {
            Toast.makeText(USBCameraActivity.this, R.string.usbdetached, Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onCancel() {
        }
    };


    //close camera
    private void closeCamera() {
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.destroy();
            mCamera = null;
        }
    }


    //init open preview
    private void startPreview() {
        if (mCamera != null && uvcView != null) {
            //mCamera.setPreviewSize(mWidth, mHeight, UVCCamera.FRAME_FORMAT_MJPEG);
            mCamera.setPreviewDisplay(uvcView.getHolder());
            mCamera.startPreview();
        }
    }

    //init camera
    private void initCamera(USBMonitor.UsbControlBlock ctrlBlock) {
        mCamera = new UVCCamera();
        mCamera.open(ctrlBlock);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (!usbMonitor.isRegistered()) return;
        //Try to start camera
        final List<UsbDevice> list = usbMonitor.getDeviceList(mFilter.get(0));
        if (list.size() > 0) {
            UsbDevice device = list.get(0);
            ToastUtils.simpleToast(getApplicationContext(), device.getDeviceName());
            if (usbMonitor.hasPermission(device)) {

                USBMonitor.UsbControlBlock ctrlBlock = new USBMonitor.UsbControlBlock(usbMonitor, device);
                initCamera(ctrlBlock);
                startPreview();
            } else {
                usbMonitor.requestPermission(device);
            }
        } else {
            CameraDialog.showDialog(USBCameraActivity.this);
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        closeCamera();
    }


    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApiIfAvailable(LocationServices.API)
                .build();
        mGoogleApiClient.connect();
    }

}
